home *** CD-ROM | disk | FTP | other *** search
/ IRIX 6.2 Applications 1996 May / SGI IRIX 6.2 Applications 1996 May.iso / dist / impr_dev.idb / usr / impressario / src / libspool / SLMain.c.z / SLMain.c
C/C++ Source or Header  |  1996-05-06  |  46KB  |  1,536 lines

  1. /**************************************************************************
  2.  *                                      *
  3.  *           Copyright (c)    1991 Silicon Graphics, Inc.          *
  4.  *            All Rights Reserved                    *
  5.  *                                      *
  6.  *       THIS    IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SGI          *
  7.  *                                      *
  8.  * The copyright notice above does not evidence any actual of intended      *
  9.  * publication of such source code, and is an unpublished work by Silicon *
  10.  * Graphics, Inc. This material contains CONFIDENTIAL INFORMATION that is *
  11.  * the property of Silicon Graphics, Inc. Any use, duplication or      *
  12.  * disclosure not specifically authorized by Silicon Graphics is strictly *
  13.  * prohibited.                                  *
  14.  *                                      *
  15.  * RESTRICTED RIGHTS LEGEND:                          *
  16.  *                                      *
  17.  * Use, duplication or disclosure by the Government is subject to      *
  18.  * restrictions as set forth in subdivision (c)(1)(ii) of the Rights in      *
  19.  * Technical Data and Computer Software clause at DFARS 52.227-7013,      *
  20.  * and/or in similar or successor clauses in the FAR, DOD or NASA FAR      *
  21.  * Supplement. Unpublished - rights reserved under the Copyright Laws of  *
  22.  * the United States. Contractor is SILICON GRAPHICS, INC., 2011 N.      *
  23.  * Shoreline Blvd., Mountain View, CA 94039-7311              *
  24.  **************************************************************************
  25.  *
  26.  * File: SLMain.c
  27.  *
  28.  * Description: This file contains all public function definitions for
  29.  *    libspool, the printer spooler API library. The public functions
  30.  *    either perform the required processing directly, call local
  31.  *    functions in this file or call spooling system specific functions
  32.  *    in the the spooling files (eg. SLBsd.c, or SLSsysV.c).
  33.  *
  34.  **************************************************************************/
  35.  
  36.  
  37. #ident "$Revision: 1.3 $"
  38.  
  39.  
  40. #include <stdio.h>
  41. #include <stdlib.h>
  42. #include <string.h>
  43. #include <unistd.h>
  44. #include <time.h>
  45. #include <ctype.h>
  46. #include <bstring.h>
  47. #include <sys/types.h>
  48. #include <sys/stat.h>
  49. #include <sys/socket.h>
  50. #include <netinet/in.h>
  51. #include <sys/un.h>
  52. #ifdef _SL_FASTPATH
  53. #include <fastprint.h>
  54. #endif /* _SL_FASTPATH */
  55. #include "spoolI.h"
  56.  
  57.  
  58. /* Possible spooling systems */
  59.  
  60. static SLSpoolerStruct pos_spooler_list[] = {
  61.     { SL_SPOOLER_BSD,
  62.         _SLBsdFindSpooler,
  63.         _SLBsdGetPrinterList,
  64.         _SLBsdGetPrinterInfo,
  65.         _SLBsdGetDefPrinterName,
  66.         _SLBsdGetPrinterSettings,
  67.         _SLBsdSubmitJob,
  68.         _SLBsdCancelJob,
  69.         _SLBsdGetSpoolerState,
  70.         _SLBsdSetSpoolerState,
  71.         _SLBsdGetQueue,
  72. #ifdef _SL_FASTPATH
  73.             _SLBsdSupportsFastJob,
  74. #endif /* _SL_FASTPATH */
  75.         _SLBsdFindUserName,
  76.     },
  77.     { SL_SPOOLER_SYSV,
  78.         _SLSysVFindSpooler,
  79.         _SLSysVGetPrinterList,
  80.         _SLSysVGetPrinterInfo,
  81.         _SLSysVGetDefPrinterName,
  82.         _SLSysVGetPrinterSettings,
  83.         _SLSysVSubmitJob,
  84.         _SLSysVCancelJob,
  85.         _SLSysVGetSpoolerState,
  86.         _SLSysVSetSpoolerState,
  87.         _SLSysVGetQueue,
  88. #ifdef _SL_FASTPATH
  89.             _SLSysVSupportsFastJob,
  90. #endif /* _SL_FASTPATH */
  91.         _SLSysVFindUserName,
  92.     },
  93.     { 0, NULL },
  94.     };
  95.  
  96.  
  97. /* Global variables */
  98.  
  99. int SLdebug;            /* Run-time debugging info provided if != 0 */
  100. long SLnet_timeout = SL_NET_TIMEOUT;    /* Timeout for network ops. (sec.) */
  101.  
  102.  
  103. /* Local variables */
  104.  
  105. static SLSpoolerStruct *def_sptr;        /* Pointer to the def spooler */
  106. static uint def_spooler = SL_SPOOLER_NONE;    /* Default spooler */
  107. static uint avail_spoolers = SL_SPOOLER_NONE;    /* Available spoolers */
  108. static SLPrintJob print_job;            /* Print job info */
  109.  
  110.  
  111. /* Local functions */
  112.  
  113. static int find_spoolers(unsigned int*);
  114. static void init_job(SLPrintJob*);
  115. static SLPrintJob* submit_job(SLJobSourceUnion*, const char*, int, int,
  116.                 int, const char*, const char*);
  117. static void sort_plist(SLPrinterStruct*, int);
  118.  
  119.  
  120. /**************************************************************************
  121.  *
  122.  * Function: SLGetSpooler
  123.  *
  124.  * Description: Returns the default spooling system for the library. If
  125.  *    the default is SL_SPOOLER_NONE, an attempt is made to determine
  126.  *    if either the SYS V lpsched or BSD lpd daemons are running.
  127.  *
  128.  * Parameters: 
  129.  *    defaultp (O) - default spooler (one of SL_SPOOLER_NONE,
  130.  *           SL_SPOOLER_BSD or SL_SPOOLER_SYSV)
  131.  *    availablep (O) - Bit mask of available spooling systems.
  132.  *
  133.  * Return: 0 indicates successful execution. -1 indicates execution error,
  134.  *    SLerrno is set.
  135.  *
  136.  **************************************************************************/
  137.  
  138. int SLGetSpooler(unsigned int *defaultp, unsigned int *availablep)
  139. {
  140.     register SLSpoolerStruct *sptr;
  141.  
  142.     /*
  143.      * If appears no spoolers are available make sure before
  144.      * reporting it
  145.      */
  146.     if (avail_spoolers == SL_SPOOLER_NONE) {
  147.     if (find_spoolers(&avail_spoolers) < 0)
  148.         RETURN_ERROR(SL_ERR_FIND_SPOOLER)
  149.     }
  150.     *availablep = avail_spoolers;
  151.  
  152.     /*
  153.      * If a spooler other than NONE is selected return that.
  154.      * Otherwise look in available spooler list and set def spooler
  155.      * from first available one in list.
  156.      */
  157.     if (def_spooler == SL_SPOOLER_NONE) {
  158.     /*
  159.      * Try to set the prefered spooler first
  160.      */
  161.     *defaultp = SL_SPOOLER_NONE;
  162.     if (avail_spoolers & SL_SPOOLER_PREF) {
  163.         *defaultp = SL_SPOOLER_PREF;
  164.         for (sptr = pos_spooler_list; sptr->find_spooler_func; sptr++) {
  165.         if (SL_SPOOLER_PREF == sptr->mask) {
  166.             def_sptr = sptr;
  167.             break;
  168.         }
  169.         }
  170.     } else {
  171.         for (sptr = pos_spooler_list; sptr->find_spooler_func; sptr++) {
  172.         if (avail_spoolers & sptr->mask) {
  173.             *defaultp = sptr->mask;
  174.             def_sptr = sptr;
  175.             break;
  176.         }
  177.         }
  178.     }
  179.     } else {
  180.     *defaultp = def_spooler;
  181.     }
  182.  
  183.     return SL_NOERROR;
  184. }
  185.  
  186.  
  187. /**************************************************************************
  188.  *
  189.  * Function: SLSetSpooler
  190.  *
  191.  * Description: Sets the default spooling system for future libspool
  192.  *    functions.
  193.  *
  194.  * Parameters: 
  195.  *    spooler (I) - spooling system to make default (eg. SL_SPOOLER_BSD).
  196.  *
  197.  * Return: 0 is returned if execution is successful. If an error has
  198.  *    occurred, -1 is returned and SLerrno is set. Note that it is
  199.  *    considered an error to request a spooling system that is not
  200.  *    available. It is also an error to specify SL_SPOOLER_NONE.
  201.  *
  202.  **************************************************************************/
  203.  
  204. int SLSetSpooler(unsigned int spooler)
  205. {
  206.     register SLSpoolerStruct *sptr;
  207.  
  208.     /*
  209.      * Make sure a spooler has been specified
  210.      */
  211.     if (spooler == SL_SPOOLER_NONE)
  212.     RETURN_ERROR(SL_ERR_SPOOLER_NONE);
  213.  
  214.     /*
  215.      * If appears no spoolers are available make sure before
  216.      * reporting an error.
  217.      */
  218.     if (avail_spoolers == SL_SPOOLER_NONE) {
  219.     if (find_spoolers(&avail_spoolers) < 0)
  220.         RETURN_ERROR(SL_ERR_FIND_SPOOLER);
  221.     if (avail_spoolers == SL_SPOOLER_NONE)
  222.         RETURN_ERROR(SL_ERR_NO_SPOOLERS);
  223.     }
  224.  
  225.     /*
  226.      * Make sure specified spooler is in list of available spoolers
  227.      * and if so set the default spooler to the specified spooler.
  228.      */
  229.     if (spooler & avail_spoolers) {
  230.         for (sptr = pos_spooler_list; sptr->find_spooler_func; sptr++) {
  231.         if (spooler & sptr->mask) {
  232.             def_spooler = spooler;
  233.         def_sptr = sptr;
  234.         break;
  235.         }
  236.         }
  237.     } else
  238.     RETURN_ERROR(SL_ERR_SPOOLER_UNKNOWN);
  239.  
  240.     return SL_NOERROR;
  241. }
  242.  
  243.  
  244. /**************************************************************************
  245.  *
  246.  * Function: SLGetPrinterList
  247.  *
  248.  * Description: Provides a list of the printers recognized by the
  249.  *    currently selected spooling system. Each time this function
  250.  *    is called the old list pointer, if any, obtained from a 
  251.  *    previous call to this function becomes invalid. If the user
  252.  *    wishes to preserve the old list, a copy must be made before
  253.  *    calling this function.
  254.  *
  255.  * Parameters: 
  256.  *    printersp (O) - set to a list of available printers. If there
  257.  *            are no printers registered with the spooler,
  258.  *            this variable will be set to NULL.
  259.  *    num_printersp (O) - number of available printers in list. If there
  260.  *                are no printers available this value will be
  261.  *                0.
  262.  *
  263.  * Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
  264.  *    error has occurred.
  265.  *
  266.  **************************************************************************/
  267.  
  268. int SLGetPrinterList(SLPrinterStruct *printersp[], int *num_printersp)
  269. {
  270.     /*
  271.      * In case no spooler make sure sane values are sent back
  272.      */
  273.     *printersp = NULL;
  274.     *num_printersp = 0;
  275.  
  276.     /*
  277.      * Make sure we have a valid spooler selected
  278.      */
  279.     CHECK_DEF_SPOOLER;
  280.  
  281.     /*
  282.      * Call the appropriate function
  283.      */
  284.     if (def_sptr->get_printers_func(printersp, num_printersp) < 0)
  285.     return SL_ERROR;
  286.  
  287.     /*
  288.      * Sort the printer list by local name
  289.      */
  290.     sort_plist(*printersp, *num_printersp);
  291.  
  292.     return SL_NOERROR;
  293. }
  294.  
  295.  
  296. /**************************************************************************
  297.  *
  298.  * Function: SLGetPrinterInfo
  299.  *
  300.  * Description: Provides detailed information about the specified printer.
  301.  *    Each time this function is called the old contents of the internal
  302.  *    info structure become invalid. If the user wishes to preserve the
  303.  *    old info, a copy must be made before calling this function.
  304.  *
  305.  * Parameters: 
  306.  *    printer (I) - printer whose info is wanted. If NULL,
  307.  *              the default printer is used.
  308.  *    printer_infop (O) - set to a printer information structure
  309.  *            filled with information about the printer. Set
  310.  *            to NULL if the specified printer does not exist.
  311.  *
  312.  * Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
  313.  *    error has occurred. It is considered an error specifying a printer
  314.  *    that is not available to the spooler.
  315.  *
  316.  **************************************************************************/
  317.  
  318. int SLGetPrinterInfo(const char *printer, SLPrinterStruct **printer_infop)
  319. {
  320.     char *def_printer;
  321.  
  322.     /*
  323.      * In case of error make sure sane values are sent back
  324.      */
  325.     *printer_infop = NULL;
  326.  
  327.     /*
  328.      * Make sure we have a valid spooler selected
  329.      */
  330.     CHECK_DEF_SPOOLER;
  331.  
  332.     /*
  333.      * Get the default printer name if no printer specified.
  334.      * Also sanity check the printer name, if specified.
  335.      */
  336.     if (!printer) {
  337.     if (SLGetDefPrinterName(&def_printer) < 0)
  338.         return SL_ERROR;
  339.     printer = def_printer;
  340.     } else if (_SLIsEmpty(printer))
  341.     RETURN_ERROR(SL_ERR_BAD_PRINTER_NAME);
  342.  
  343.     /*
  344.      * Call the appropriate function
  345.      */
  346.     if (def_sptr->get_printer_info_func(printer, printer_infop) < 0)
  347.     return SL_ERROR;
  348.  
  349.     return SL_NOERROR;
  350. }
  351.  
  352.  
  353. /**************************************************************************
  354.  *
  355.  * Function: SLGetDefPrinterName
  356.  *
  357.  * Description: Returns the name of the default printer for the currently
  358.  *    selected spooliong system.
  359.  *
  360.  * Parameters: 
  361.  *    pnamep (O) - set to the name of the default printer or to
  362.  *             NULL if no printer is registered as the default.
  363.  *
  364.  * Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
  365.  *    error has occurred.
  366.  *
  367.  **************************************************************************/
  368.  
  369. int SLGetDefPrinterName(char **pnamep)
  370. {
  371.     /*
  372.      * In case no spooler make sure sane values are sent back
  373.      */
  374.     *pnamep = NULL;
  375.  
  376.     /*
  377.      * Make sure we have a valid spooler selected
  378.      */
  379.     CHECK_DEF_SPOOLER;
  380.  
  381.     /*
  382.      * Call the appropriate function
  383.      */
  384.     if (def_sptr->get_def_printer_func(pnamep) < 0)
  385.     return SL_ERROR;
  386.  
  387.     return SL_NOERROR;
  388. }
  389.  
  390.  
  391. /**************************************************************************
  392.  *
  393.  * Function: SLGetPrinterSettings
  394.  *
  395.  * Description: Reads the spooler and printer option settings that have
  396.  *    been saved by the SL settings save functions (e.g.
  397.  *    SLSysVSaveSpoolerOptions and SLSysVSavePrinterOptions).
  398.  *    The settings are returned in a spooling system independ format.
  399.  *    Each time this function is called the old contents of the internal
  400.  *    settings structure becomes invalid. If the caller wishes to
  401.  *    preserve the old settings information, a copy must be made before
  402.  *    calling this function.
  403.  *
  404.  *    Note that calling this function does not effect the contents of
  405.  *    the settings files stored on disk. If settings files for the
  406.  *    specified printer are not found, default settings appropriate to
  407.  *    the default behavior of the current spooler are returned. 
  408.  *
  409.  * Parameters: 
  410.  *    printer (I) - printer whose settings are wanted. If NULL,
  411.  *              the default printer is used. If the printer
  412.  *              specified does not exist, the default settings
  413.  *              for the current spooler will be returned.
  414.  *    settingsp (O) - set to a printer settings structure
  415.  *            filled with the currently saved spooler
  416.  *            and printer option settings.
  417.  *
  418.  * Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
  419.  *    error has occurred.
  420.  *
  421.  **************************************************************************/
  422.  
  423. int SLGetPrinterSettings(const char *printer, SLSettingsStruct **settingsp)
  424. {
  425.     char *def_printer;
  426.  
  427.     /*
  428.      * In case of error make sure sane values are sent back
  429.      */
  430.     *settingsp = NULL;
  431.  
  432.     /*
  433.      * Make sure we have a valid spooler selected
  434.      */
  435.     CHECK_DEF_SPOOLER;
  436.  
  437.     /*
  438.      * Get the default printer name if no printer specified.
  439.      * Also sanity check the printer name, if specified.
  440.      */
  441.     if (!printer) {
  442.     if (SLGetDefPrinterName(&def_printer) < 0)
  443.         return SL_ERROR;
  444.     printer = def_printer;
  445.     } else if (_SLIsEmpty(printer))
  446.     RETURN_ERROR(SL_ERR_BAD_PRINTER_NAME);
  447.  
  448.     /*
  449.      * Call the appropriate function
  450.      */
  451.     if (def_sptr->get_printer_settings_func(printer, settingsp) < 0)
  452.     return SL_ERROR;
  453.  
  454.     return SL_NOERROR;
  455. }
  456.  
  457.  
  458. /**************************************************************************
  459.  *
  460.  * Function: SLSysVGetSpoolerOptions
  461.  *
  462.  * Description: Reads the spooler option settings that have
  463.  *    been saved by SLSysVSaveSpoolerOptions. The options are
  464.  *    returned in a format consistent with the System V spooling system.
  465.  *    Each time this function is called the old contents of the internal
  466.  *    settings structure becomes invalid. If the caller wishes to
  467.  *    preserve the old settings information, a copy must be made before
  468.  *    calling this function.
  469.  *
  470.  *    Note that calling this function does not effect the contents of
  471.  *    the settings files stored on disk. If a spooler option file is
  472.  *    not found for the calling user, default settings are returned.
  473.  *
  474.  * Parameters: 
  475.  *    spooler_optsp (O) - set to a spooler options structure
  476.  *            filled with the currently saved spooler options
  477.  *            or default values if no spooler options file
  478.  *            is found.
  479.  *
  480.  * Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
  481.  *    error has occurred. It is considered an error to call this function
  482.  *    if the System V spooler is not the currently set spooling system.
  483.  *
  484.  **************************************************************************/
  485.  
  486. int SLSysVGetSpoolerOptions(SLSysVSpoolerOptionsStruct **spooler_optsp)
  487. {
  488.     /*
  489.      * In case of error make sure sane values are sent back
  490.      */
  491.     *spooler_optsp = NULL;
  492.  
  493.     /*
  494.      * Make sure we have the System V spooler set otherwise
  495.      * we return an error indication.
  496.      */
  497.     CHECK_DEF_SPOOLER;
  498.     if (def_sptr->mask != SL_SPOOLER_SYSV)
  499.     RETURN_ERROR(SL_ERR_NO_SYSV);
  500.  
  501.     /*
  502.      * Call the appropriate function
  503.      */
  504.     if (_SLSysVGetSpoolerOptions(spooler_optsp) < 0)
  505.     return SL_ERROR;
  506.  
  507.     return SL_NOERROR;
  508. }
  509.  
  510.  
  511. /**************************************************************************
  512.  *
  513.  * Function: SLSysVGetPrinterOptions
  514.  *
  515.  * Description: Reads the printer specific option settings that have
  516.  *    been saved by SLSysVSavePrinterOptions. The printer options
  517.  *    consists of a string of printer specific options that would
  518.  *    typically be specified on the lp command line using the "-o"
  519.  *    switch. Each time this function is called the old contents of
  520.  *    the internal string storage becomes invalid. If the caller wishes to
  521.  *    preserve the old information, a copy must be made before
  522.  *    calling this function.
  523.  *
  524.  *    Note that calling this function does not effect the contents of
  525.  *    the settings files stored on disk. If there are no pritner specific
  526.  *    settings saved for the specified printer, the options string
  527.  *    is returned as NULL.
  528.  *
  529.  * Parameters: 
  530.  *    printer (I) - printer whose options are wanted. If NULL,
  531.  *              the default printer is used.
  532.  *    printer_optsp (O) - set to point to a printer specific options
  533.  *            string or NULL if no printer specific options
  534.  *            set for this printer or the printer does not
  535.  *            exist.
  536.  *
  537.  * Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
  538.  *    error has occurred. It is considered an error to call this function
  539.  *    if the System V spooler is not the currently set spooling system.
  540.  *
  541.  **************************************************************************/
  542.  
  543. int SLSysVGetPrinterOptions(const char *printer, char **printer_optsp)
  544. {
  545.     char *def_printer;
  546.  
  547.     /*
  548.      * In case of error make sure sane values are sent back
  549.      */
  550.     *printer_optsp = NULL;
  551.  
  552.     /*
  553.      * Make sure we have the System V spooler set otherwise
  554.      * we return an error indication.
  555.      */
  556.     CHECK_DEF_SPOOLER;
  557.     if (def_sptr->mask != SL_SPOOLER_SYSV)
  558.     RETURN_ERROR(SL_ERR_NO_SYSV);
  559.  
  560.     /*
  561.      * Get the default printer name if no printer specified.
  562.      * Also sanity check the printer name, if specified.
  563.      */
  564.     if (!printer) {
  565.     if (SLGetDefPrinterName(&def_printer) < 0)
  566.         return SL_ERROR;
  567.     printer = def_printer;
  568.     } else if (_SLIsEmpty(printer))
  569.     RETURN_ERROR(SL_ERR_BAD_PRINTER_NAME);
  570.  
  571.     /*
  572.      * Call the appropriate function
  573.      */
  574.     if (_SLSysVGetPrinterOptions(printer, printer_optsp) < 0)
  575.     return SL_ERROR;
  576.  
  577.     return SL_NOERROR;
  578. }
  579.  
  580.  
  581. /**************************************************************************
  582.  *
  583.  * Function: SLSysVSaveSpoolerOptions
  584.  *
  585.  * Description: Saves the System V spooler specific options.
  586.  *
  587.  * Parameters: 
  588.  *    spooler_opts (I) - settings to save.
  589.  *
  590.  * Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
  591.  *    error has occurred. It is considered an error to call this function
  592.  *    if the System V spooler is not the currently set spooling system.
  593.  *
  594.  **************************************************************************/
  595.  
  596. int SLSysVSaveSpoolerOptions(SLSysVSpoolerOptionsStruct *spooler_opts)
  597. {
  598.     /*
  599.      * Make sure we have the System V spooler set otherwise
  600.      * we return an error indication.
  601.      */
  602.     CHECK_DEF_SPOOLER;
  603.     if (def_sptr->mask != SL_SPOOLER_SYSV)
  604.     RETURN_ERROR(SL_ERR_NO_SYSV);
  605.  
  606.     /*
  607.      * Call the appropriate function
  608.      */
  609.     if (_SLSysVSaveSpoolerOptions(spooler_opts) < 0)
  610.     return SL_ERROR;
  611.  
  612.     return SL_NOERROR;
  613. }
  614.  
  615.  
  616. /**************************************************************************
  617.  *
  618.  * Function: SLSysVSavePrinterOptions
  619.  *
  620.  * Description: Saves the System V printer specific option settings.
  621.  *
  622.  * Parameters: 
  623.  *    printer (I) - printer whose options are to be saved. If NULL,
  624.  *              the default printer is used.
  625.  *    printer_opts (I) - options to save.
  626.  *    location (I) - Save settings for this user (SL_SAVE_USER) or
  627.  *            for all users (SL_SAVE_DEFAULT). Note that for
  628.  *            default save to work you must be either 'root'
  629.  *            or 'lp' according to your current uid.
  630.  *
  631.  * Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
  632.  *    error has occurred. It is considered an error to call this function
  633.  *    if the System V spooler is not the currently set spooling system.
  634.  *
  635.  **************************************************************************/
  636.  
  637. int SLSysVSavePrinterOptions(const char *printer,
  638.                 char *printer_opts, int location)
  639. {
  640.     char *def_printer;
  641.  
  642.     /*
  643.      * Sanity checks location
  644.      */
  645.     if (location != SL_SAVE_USER && location != SL_SAVE_DEFAULT)
  646.     location = SL_SAVE_USER;
  647.  
  648.     /*
  649.      * Make sure we have the System V spooler set otherwise
  650.      * we return an error indication.
  651.      */
  652.     CHECK_DEF_SPOOLER;
  653.     if (def_sptr->mask != SL_SPOOLER_SYSV)
  654.     RETURN_ERROR(SL_ERR_NO_SYSV);
  655.  
  656.     /*
  657.      * Get the default printer name if no printer specified.
  658.      * Also sanity check the printer name, if specified.
  659.      */
  660.     if (!printer) {
  661.     if (SLGetDefPrinterName(&def_printer) < 0)
  662.         return SL_ERROR;
  663.     printer = def_printer;
  664.     } else if (_SLIsEmpty(printer))
  665.     RETURN_ERROR(SL_ERR_BAD_PRINTER_NAME);
  666.  
  667.     /*
  668.      * Call the appropriate function
  669.      */
  670.     if (_SLSysVSavePrinterOptions(printer, printer_opts, location) < 0)
  671.     return SL_ERROR;
  672.  
  673.     return SL_NOERROR;
  674. }
  675.  
  676.  
  677. /**************************************************************************
  678.  *
  679.  * Function: SLSubmitJob
  680.  *
  681.  * Description: Submits a job for printing. A print job structure pointer
  682.  *    is returned that can be used to subsequently cancel or track the
  683.  *    status of the job. This pointer is reused by this function so users
  684.  *    wishing to preserve the data in the structure should copy the
  685.  *    structure.
  686.  *
  687.  * Parameters: 
  688.  *    filename (I) - file(s) to print. Wildcards acceptable. Multiple
  689.  *               filenames should be separated by whitespace.
  690.  *    printer (I) - printer on which to print job. If NULL then default
  691.  *              printer is used.
  692.  *    num_copies (I) - number of copies
  693.  *    copy (I) - Copy flag. If 1 then file is copied to spooling dir. If
  694.  *           0 a link is created.
  695.  *    mail (I) - Mail flag. If 1 then mail is sent on job print completion.
  696.  *           If 0, no mail is sent.
  697.  *    title (I) - title to appear on banner page.
  698.  *    options (I) - string of spooling system/printer specific options.
  699.  *              Set to NULL if none.
  700.  *
  701.  * Return: If no error, a pointer to a print job structure is returned. If
  702.  *    the information in this structure is to be maintained and more jobs
  703.  *    are to be submitted, this structure should be copied to a user buffer.
  704.  *    NULL is returned and SLerrno is set if an error has occurred.
  705.  *
  706.  **************************************************************************/
  707.  
  708. SLPrintJob* SLSubmitJob(const char *filename, const char *printer,
  709.             int num_copies, int copy, int mail,
  710.             const char *title, const char *options)
  711. {
  712.     SLJobSourceUnion job_source;
  713.     SLPrintJob *pjob;
  714.  
  715.     /*
  716.      * Perform basic sanity check on the filename
  717.      */
  718.     if (!filename || _SLIsEmpty(filename))
  719.     RETURN_ERROR_PTR(SL_ERR_NO_FILENAME);
  720.  
  721.     /*
  722.      * File out the job source structure
  723.      */
  724.     job_source.type = SL_JOB_FILENAME;
  725.     job_source.filename_job.filename = filename;
  726.  
  727.     /*
  728.      * Call the generic job submittal routine
  729.      */
  730.     pjob = submit_job(&job_source, printer, num_copies, copy, mail, title,
  731.             options);
  732.  
  733.     return pjob;
  734. }
  735.  
  736.  
  737. /**************************************************************************
  738.  *
  739.  * Function: SLSubmitJobFd
  740.  *
  741.  * Description: Submits a job for printing. The source for the print job
  742.  *    is the specified file descriptor. A print job structure pointer
  743.  *    is returned that can be used to subsequently cancel or track the
  744.  *    status of the job. This pointer is reused by this function so users
  745.  *    wishing to preserve the data in the structure should copy the
  746.  *    structure.
  747.  *
  748.  * Parameters: 
  749.  *    file_desc (I) - File descriptor of a file open for reading.
  750.  *                The contents of this file is printed.
  751.  *    printer (I) - printer on which to print job. If NULL then default
  752.  *              printer is used.
  753.  *    num_copies (I) - number of copies
  754.  *    copy (I) - Copy flag. If 1 then file is copied to spooling dir. If
  755.  *           0 a link is created.
  756.  *    mail (I) - Mail flag. If 1 then mail is sent on job print completion.
  757.  *           If 0, no mail is sent.
  758.  *    title (I) - title to appear on banner page.
  759.  *    options (I) - string of spooling system/printer specific options.
  760.  *              Set to NULL if none.
  761.  *
  762.  * Return: If no error, a pointer to a print job structure is returned. If
  763.  *    the information in this structure is to be maintained and more jobs
  764.  *    are to be submitted, this structure should be copied to a user buffer.
  765.  *    NULL is returned and SLerrno is set if an error has occurred.
  766.  *
  767.  **************************************************************************/
  768.  
  769. SLPrintJob* SLSubmitJobFd(int file_desc, const char *printer,
  770.                 int num_copies, int copy, int mail,
  771.                 const char *title, const char *options)
  772. {
  773.     SLJobSourceUnion job_source;
  774.     struct stat sbuf;
  775.  
  776.     /*
  777.      * Perform basic sanity check on the file descriptor
  778.      */
  779.     if (fstat(file_desc, &sbuf) < 0)
  780.     RETURN_ERROR_PTR(SL_ERR_BAD_FD);
  781.  
  782.     /*
  783.      * File out the job source structure
  784.      */
  785.     job_source.type = SL_JOB_FD;
  786.     job_source.fd_job.file_desc = file_desc;
  787.  
  788.     /*
  789.      * Call the generic job submittal routine
  790.      */
  791.     return submit_job(&job_source, printer, num_copies, copy, mail, title,
  792.             options);
  793. }
  794.  
  795.  
  796. /**************************************************************************
  797.  *
  798.  * Function: SLSubmitJobBuf
  799.  *
  800.  * Description: Submits a job for printing. The source for the print job
  801.  *    is the specified buffer of the specified size (in bytes). A print
  802.  *    job structure pointer is returned that can be used to subsequently
  803.  *    cancel or track the status of the job. This pointer is reused by
  804.  *    this function so users wishing to preserve the data in the structure
  805.  *    should copy the structure.
  806.  *
  807.  * Parameters: 
  808.  *    buffer (I) - buffer whose contents are to be printed.
  809.  *    amount (I) - number of bytes in buffer.
  810.  *    printer (I) - printer on which to print job. If NULL then default
  811.  *              printer is used.
  812.  *    num_copies (I) - number of copies
  813.  *    copy (I) - Copy flag. If 1 then file is copied to spooling dir. If
  814.  *           0 a link is created.
  815.  *    mail (I) - Mail flag. If 1 then mail is sent on job print completion.
  816.  *           If 0, no mail is sent.
  817.  *    title (I) - title to appear on banner page.
  818.  *    options (I) - string of spooling system/printer specific options.
  819.  *              Set to NULL if none.
  820.  *
  821.  * Return: If no error, a pointer to a print job structure is returned. If
  822.  *    the information in this structure is to be maintained and more jobs
  823.  *    are to be submitted, this structure should be copied to a user buffer.
  824.  *    NULL is returned and SLerrno is set if an error has occurred.
  825.  *
  826.  **************************************************************************/
  827.  
  828. SLPrintJob* SLSubmitJobBuf(const void *buffer, size_t amount,
  829.                 const char *printer, int num_copies,
  830.                 int copy, int mail, const char *title,
  831.                 const char *options)
  832. {
  833.     SLJobSourceUnion job_source;
  834.  
  835.     /*
  836.      * Perform basic sanity check on the file descriptor
  837.      */
  838.     if (!buffer || !amount)
  839.     RETURN_ERROR_PTR(SL_ERR_BAD_BUF);
  840.  
  841.     /*
  842.      * File out the job source structure
  843.      */
  844.     job_source.type = SL_JOB_BUF;
  845.     job_source.buf_job.buffer = buffer;
  846.     job_source.buf_job.amount = amount;
  847.  
  848.     /*
  849.      * Call the generic job submittal routine
  850.      */
  851.     return submit_job(&job_source, printer, num_copies, copy, mail, title,
  852.             options);
  853. }
  854.  
  855.  
  856. /**************************************************************************
  857.  *
  858.  * Function: SLSubmitJobSimple
  859.  *
  860.  * Description: Submits a job for printing. This function provides a
  861.  *    simple job submittal interface for users who wish to accept
  862.  *    all defaults. The default printer with the default options 
  863.  *    are used to print the job.
  864.  *
  865.  * Parameters: 
  866.  *    filename (I) - file(s) to print. Wildcards acceptable. Multiple
  867.  *               filenames should be separated by whitespace.
  868.  *
  869.  * Return: If no error, a pointer to a print job structure is returned. If
  870.  *    the information in this structure is to be maintained and more jobs
  871.  *    are to be submitted, this structure should be copied to a user buffer.
  872.  *    NULL is returned and SLerrno is set if an error has occurred.
  873.  *
  874.  **************************************************************************/
  875.  
  876. SLPrintJob* SLSubmitJobSimple(const char *filename)
  877. {
  878.     /*
  879.      * Simply call SLSubmit Job with fields filled in
  880.      */
  881.     return SLSubmitJob(filename, NULL, 1, 0, 0, NULL, NULL);
  882. }
  883.  
  884.  
  885. /**************************************************************************
  886.  *
  887.  * Function: SLCancelJob
  888.  *
  889.  * Description: Makes a request to the specified spooling system to cancel
  890.  *    the specified job. The following notes apply:
  891.  *
  892.  *    1. No confirmation that the job was found and canceled is
  893.  *       provided.
  894.  *
  895.  *    2. If spooler is SL_SPOOLER_NONE, the current spooling system
  896.  *       will be used. If a spooler is specified, the job will be
  897.  *       canceled on that spooling system, but the specified spooling
  898.  *       system will not become the default spooling system.
  899.  *
  900.  *    3. For System V print jobs the printer parameter is ignored and
  901.  *       may be set to NULL. This is because the printer for the job
  902.  *       is extracted from the job_id.
  903.  *
  904.  *    4. For BSD print jobs if the printer parameter is NULL, the current
  905.  *       default printer is assumed.
  906.  *
  907.  * Parameters: 
  908.  *    job_id (I) - job ID(s) of the print jobs to be canceled. Multiple
  909.  *             IDs should be separated by whitepsace.
  910.  *    spooler (I) - print spooler to which job was submitted.
  911.  *    printer (I) - printer to which job was submitted.
  912.  *
  913.  * Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
  914.  *    error has occurred.
  915.  *
  916.  **************************************************************************/
  917.  
  918. int SLCancelJob(const char *job_id, unsigned int spooler, const char *printer)
  919. {
  920.     register SLSpoolerStruct *sptr;
  921.  
  922.     /*
  923.      * Make sure we have a valid spooler selected
  924.      */
  925.     CHECK_DEF_SPOOLER;
  926.  
  927.     /*
  928.      * Perform basic sanity checks on parameters
  929.      */
  930.     if (!job_id || _SLIsEmpty(job_id))
  931.     RETURN_ERROR(SL_ERR_NO_JOBID);
  932.  
  933.     /*
  934.      * If no spooler specified use the default spooler's
  935.      * function. If a spooler is specified, make sure that
  936.      * it is valid and call that spooler's cancel function
  937.      */
  938.     if (spooler == SL_SPOOLER_NONE)
  939.     sptr = def_sptr;
  940.     else if (spooler & avail_spoolers)
  941.         for (sptr = pos_spooler_list; !(spooler & sptr->mask); sptr++)
  942.         ;
  943.     else
  944.     RETURN_ERROR(SL_ERR_SPOOLER_UNKNOWN);
  945.  
  946.     if (sptr->cancel_job_func(job_id, printer) < 0)
  947.         return SL_ERROR;
  948.  
  949.     return SL_NOERROR;
  950. }
  951.  
  952.  
  953. /**************************************************************************
  954.  *
  955.  * Function: SLGetSpoolerState
  956.  *
  957.  * Description: Returns the state of the specified spooling function.
  958.  *
  959.  * Parameters: 
  960.  *    printer (I) - printer whose spooler state to query. If NULL,
  961.  *              the default printer is used.
  962.  *    function (I) - spooling function whose state to query (one of
  963.  *               SL_PRINTING or SL_QUEUEING).
  964.  *    statep (O) - state of the spooling function (one of SL_ENABLED or
  965.  *             SL_DISABLED).
  966.  *
  967.  * Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
  968.  *    error has occurred.
  969.  *
  970.  **************************************************************************/
  971.  
  972. int SLGetSpoolerState(const char *printer, int function, int *statep)
  973. {
  974.     char *def_printer;
  975.  
  976.     /*
  977.      * In case of error make sure sane values are sent back
  978.      */
  979.     *statep = SL_DISABLED;
  980.  
  981.     /*
  982.      * Make sure we have a valid spooler selected
  983.      */
  984.     CHECK_DEF_SPOOLER;
  985.  
  986.     /*
  987.      * Perform basic sanity checks on the parameters
  988.      */
  989.     if (function != SL_PRINTING && function != SL_QUEUEING)
  990.     RETURN_ERROR(SL_ERR_BAD_FUNCTION);
  991.  
  992.     /*
  993.      * Get the default printer name if no printer specified
  994.      * and do some sanity checking if a printer was specified.
  995.      */
  996.     if (!printer) {
  997.     if (SLGetDefPrinterName(&def_printer) < 0)
  998.         return SL_ERROR;
  999.     printer = def_printer;
  1000.     } else if (_SLIsEmpty(printer))
  1001.     RETURN_ERROR(SL_ERR_BAD_PRINTER_NAME);
  1002.  
  1003.     /*
  1004.      * Call the appropriate function
  1005.      */
  1006.     if (def_sptr->get_spooler_state_func(printer, function, statep) < 0)
  1007.     return SL_ERROR;
  1008.  
  1009.     return SL_NOERROR;
  1010. }
  1011.  
  1012.  
  1013. /**************************************************************************
  1014.  *
  1015.  * Function: SLSetSpoolerState
  1016.  *
  1017.  * Description: Sets the state of the specified spooling function.
  1018.  *    You must have an euid of root to execute this function.
  1019.  *
  1020.  * Parameters: 
  1021.  *    printer (I) - printer whose spooler state to set. If NULL,
  1022.  *              the default printer is used.
  1023.  *    function (I) - spooling function whose state to set (one of
  1024.  *               SL_PRINTING or SL_QUEUEING).
  1025.  *    state (I) - state to set for the spooling function (one of
  1026.  *             SL_ENABLED or SL_DISABLED).
  1027.  *
  1028.  * Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
  1029.  *    error has occurred.
  1030.  *
  1031.  **************************************************************************/
  1032.  
  1033. int SLSetSpoolerState(const char *printer, int function, int state)
  1034. {
  1035.     char *def_printer;
  1036.  
  1037.     /*
  1038.      * Make sure we have a valid spooler selected
  1039.      */
  1040.     CHECK_DEF_SPOOLER;
  1041.  
  1042.     /*
  1043.      * Perform basic sanity checks on the parameters
  1044.      */
  1045.     if (function != SL_PRINTING && function != SL_QUEUEING)
  1046.     RETURN_ERROR(SL_ERR_BAD_FUNCTION);
  1047.     if (state != SL_ENABLED && state != SL_DISABLED)
  1048.     RETURN_ERROR(SL_ERR_BAD_STATE);
  1049.  
  1050.     /*
  1051.      * Get the default printer name if no printer specified
  1052.      * and do sanity checking if a printer was specified.
  1053.      */
  1054.     if (!printer) {
  1055.     if (SLGetDefPrinterName(&def_printer) < 0)
  1056.         return SL_ERROR;
  1057.     printer = def_printer;
  1058.     } else if (_SLIsEmpty(printer))
  1059.     RETURN_ERROR(SL_ERR_BAD_PRINTER_NAME);
  1060.  
  1061.     /*
  1062.      * Call the appropriate function
  1063.      */
  1064.     if (def_sptr->set_spooler_state_func(printer, function, state) < 0)
  1065.     return SL_ERROR;
  1066.  
  1067.     return SL_NOERROR;
  1068. }
  1069.  
  1070.  
  1071. /**************************************************************************
  1072.  *
  1073.  * Function: SLGetQueue
  1074.  *
  1075.  * Description: Returns the job queue for the specified printer. Note that
  1076.  *    this function requires a printer structure passed as opposed to a
  1077.  *    printer name. This is because the printer structure contains info
  1078.  *    regarding whether the printer is remote and if so, where it is
  1079.  *    located. Note that the any old pointer to the queue will be invalid
  1080.  *    after this call. To save a previous queue the queue structures
  1081.  *    must be copied.
  1082.  *
  1083.  * Parameters: 
  1084.  *    printer_info (I) - printer structure. Cannot be NULL.
  1085.  *    queue_type (I) - type of queue to obtain (ie. local, remote or
  1086.  *                merged. Ignored for local printers and for
  1087.  *                BSD spooler.
  1088.  *    queuep (O) - print queue entries.
  1089.  *    num_queuep (O) - number of entries in the queue.
  1090.  *
  1091.  * Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
  1092.  *    error has occurred.
  1093.  *
  1094.  **************************************************************************/
  1095.  
  1096. int SLGetQueue(const SLPrinterStruct *printer_info, int queue_type, 
  1097.                 SLQueueStruct *queuep[], int *num_queuep)
  1098. {
  1099.     /*
  1100.      * In case no spooler make sure sane values are sent back
  1101.      */
  1102.     *queuep = NULL;
  1103.     *num_queuep = 0;
  1104.  
  1105.     /*
  1106.      * Make sure we have a valid spooler selected
  1107.      */
  1108.     CHECK_DEF_SPOOLER;
  1109.  
  1110.     /*
  1111.      * Perform basic sanity checks on the parameters
  1112.      */
  1113.     if (!printer_info)
  1114.     RETURN_ERROR(SL_ERR_BAD_PRINTER_STRUCT);
  1115.  
  1116.     /*
  1117.      * Call the appropriate function
  1118.      */
  1119.     if (def_sptr->get_queue_func(printer_info, queue_type,
  1120.                         queuep, num_queuep) < 0)
  1121.     return SL_ERROR;
  1122.  
  1123.     return SL_NOERROR;
  1124. }
  1125.  
  1126.  
  1127. /**************************************************************************
  1128.  *
  1129.  * Function: SLGetSpoolerError
  1130.  *
  1131.  * Description: If SLerrno == SL_ERR_SPOOLER_ERROR this function can
  1132.  *    be called to get the spooler error message(s), if any. This
  1133.  *    function first checks SLerrno to verify that it is set to
  1134.  *    SL_ERR_SPOOLER_ERROR. If it is not, then the function sets
  1135.  *    noutp to 0 and returns. The function returns a list of strings
  1136.  *    which comprise the output from the spooling system and a count
  1137.  *    of the number of lines of output.
  1138.  *
  1139.  * Parameters: 
  1140.  *    out_bufp (O) - list of strings comprising the output from the
  1141.  *               spooling system.
  1142.  *    noutp (O) - number of lines of output.
  1143.  *
  1144.  * Return: Exit status of spooler command that caused the error.
  1145.  *
  1146.  **************************************************************************/
  1147.  
  1148. int SLGetSpoolerError(char **out_bufp[], int *noutp)
  1149. {
  1150.     /*
  1151.      * Make sure that last error was a spooler error
  1152.      */
  1153.     if (SLerrno != SL_ERR_SPOOLER_ERROR) {
  1154.     *noutp = 0;
  1155.     return 0;
  1156.     }
  1157.  
  1158.     /*
  1159.      * Set parameters to the buffer globals
  1160.      */
  1161.     *out_bufp = _SLspooler_out_buf;
  1162.     *noutp = _SLspooler_nout;
  1163.  
  1164.     /*
  1165.      * Return spooler command exit code
  1166.      */
  1167.     return _SLspooler_exit;
  1168. }
  1169.  
  1170.  
  1171. #ifdef _SL_FASTPATH
  1172. /**************************************************************************
  1173.  *
  1174.  * Function: SLBeginFastJob
  1175.  *
  1176.  * Description:
  1177.  *      Submit a job to the fast path through the spooling system.
  1178.  *      The idea is that for enormous print jobs, it is very wasteful
  1179.  *      to write all the data to disk, and then have it copied around
  1180.  *      the spooling system, and finally piped to the printer driver.
  1181.  *      Instead, this function in cooperation with the model file for
  1182.  *      the printer sets up a socket so the application can
  1183.  *      communicate directly with the scanner driver, or at least to
  1184.  *      the filters that must be invoked to preprocess the data.
  1185.  *
  1186.  * Parameters:
  1187.  *      printer  Printer to send data to
  1188.  *      ncopies  Number of copies to print
  1189.  *      mail     Mail on completion
  1190.  *      title    title of job
  1191.  *      options  printer specific options
  1192.  *
  1193.  * Return: Pointer to a SLFastPrintJob if successful, NULL if error
  1194.  *
  1195.  **************************************************************************/
  1196.  
  1197. SLFastPrintJob* SLBeginFastJob(const char *printer, int ncopies,
  1198.            int mail, const char *title, const char *options)
  1199. {
  1200.     int sock;
  1201.     FASTHEADER header;
  1202.     SLFastPrintJob *fj = 0;
  1203.     SLPrintJob *job;
  1204.  
  1205.     if (!SLSupportsFastJob(printer)) {
  1206.     RETURN_ERROR_PTR(SL_ERR_NO_FAST_JOB);
  1207.     }
  1208.  
  1209.     if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
  1210.     RETURN_ERROR_PTR(SL_ERR_BAD_SOCKET);
  1211.     }
  1212.  
  1213.     header.magic = FASTMAGIC;
  1214.     header.ftype = 0;
  1215.     header.addrlen = sizeof(header.addr.in);
  1216.  
  1217.     if (listen(sock, 1) < 0
  1218.     || getsockname(sock, &header.addr.in, &header.addrlen) < 0) {
  1219.     if (SLdebug) {
  1220.         perror("socket");
  1221.     }
  1222.     (void)close(sock);
  1223.     RETURN_ERROR_PTR(SL_ERR_BAD_SOCKET);
  1224.     }
  1225.  
  1226.     job = SLSubmitJobBuf(&header, sizeof(header), printer, ncopies,
  1227.              1, mail, title, options);
  1228.  
  1229.     if (job) {
  1230.     fj = malloc(sizeof(*fj));
  1231.     fj->job = malloc(sizeof(fj->job));
  1232.     bcopy(job, fj->job, sizeof(fj->job));
  1233.     fj->sock = sock;
  1234.     } else {
  1235.     (void)close(sock);
  1236.     }
  1237.  
  1238.     return fj;
  1239. }
  1240.  
  1241.  
  1242. /**************************************************************************
  1243.  *
  1244.  * Function: SLCancelFastJob
  1245.  *
  1246.  * Description:
  1247.  *     Interrupt a fast print job.
  1248.  *
  1249.  * Parameters:
  1250.  *      fj  The fast job to interrupt
  1251.  *
  1252.  * Return: 0 if successful, -1 if error
  1253.  *
  1254.  **************************************************************************/
  1255.  
  1256. int SLCancelFastJob(SLFastPrintJob *fj)
  1257. {
  1258.     (void)SLCancelJob(fj->job->job_id, fj->job->spooler, fj->job->printer);
  1259.     (void)SLEndFastJob(fj);
  1260.     return 0;
  1261. }
  1262.  
  1263.  
  1264. /**************************************************************************
  1265.  *
  1266.  * Function:  SLEndFastJob
  1267.  *
  1268.  * Description:
  1269.  *      Terminate a fast print job normally.  To be called when all
  1270.  *      data has been sent.  Frees resources associated with a fast
  1271.  *      print job.
  1272.  *
  1273.  * Parameters:
  1274.  *      fj  The fast job to terminate
  1275.  *
  1276.  * Return: 0 if successful, -1 if error
  1277.  *
  1278.  **************************************************************************/
  1279.  
  1280. int SLEndFastJob(SLFastPrintJob *fj)
  1281. {
  1282.     (void)close(fj->sock);
  1283.     free(fj->job);
  1284.     free(fj);
  1285.     return 0;
  1286. }
  1287.  
  1288.  
  1289. /**************************************************************************
  1290.  *
  1291.  * Function: SLSupportsFastJob
  1292.  *
  1293.  * Description:
  1294.  *      Find out whether a printer supports fast print jobs
  1295.  *
  1296.  * Parameters:
  1297.  *      printer  printer to find out if supports fast jobs
  1298.  *
  1299.  * Return: non-zero if fast job supported, 0 otherwise
  1300.  *
  1301.  **************************************************************************/
  1302.  
  1303. int
  1304. SLSupportsFastJob(const char *printer)
  1305. {
  1306.     CHECK_DEF_SPOOLER;
  1307.     return def_sptr->supports_fast_job(printer);
  1308. }
  1309. #endif /* _SL_FASTPATH */
  1310.  
  1311.  
  1312. /*
  1313.  ==========================================================================
  1314.             LOCAL FUNCTIONS
  1315.  ==========================================================================
  1316. */
  1317.  
  1318.  
  1319. /**************************************************************************
  1320.  *
  1321.  * Function: find_spoolers
  1322.  *
  1323.  * Description: Supervises the determination of which print spoolers are
  1324.  *    available. This is based on a determination of whether the spooler's
  1325.  *    scheduler is running.
  1326.  *
  1327.  * Parameters:
  1328.  *    spoolersp (O) - bit mask of available spoolers
  1329.  *
  1330.  * Return: 0 if success, -1 if error. SLerrno is not set.
  1331.  *
  1332.  **************************************************************************/
  1333.  
  1334. static int find_spoolers(unsigned int *spoolersp)
  1335. {
  1336.     register SLSpoolerStruct *sptr;
  1337.  
  1338.     /*
  1339.      * Based on the list of possible spoolers see which one's
  1340.      * demon(s) is around.
  1341.      */
  1342.     *spoolersp = SL_SPOOLER_NONE;
  1343.     for (sptr = pos_spooler_list; sptr->find_spooler_func; sptr++) {
  1344.     if (sptr->find_spooler_func())
  1345.             *spoolersp |= sptr->mask;
  1346.     }
  1347.  
  1348.     return 0;
  1349. }
  1350.  
  1351. /**************************************************************************
  1352.  *
  1353.  * Function: init_job
  1354.  *
  1355.  * Description: Deallocates the storage associated with the members of
  1356.  *    a printer job structure and initializes other fields.
  1357.  *
  1358.  * Parameters:
  1359.  *    job (I) - printer job whose storage is to be deallocated.
  1360.  *
  1361.  * Return: none
  1362.  *
  1363.  **************************************************************************/
  1364.  
  1365. static void init_job(SLPrintJob *job)
  1366. {
  1367.     job->spooler = SL_SPOOLER_NONE;
  1368.     if (job->printer) {
  1369.     free((char*)job->printer);
  1370.     job->printer = NULL;
  1371.     }
  1372.     if (job->filename) {
  1373.     free((char*)job->filename);
  1374.     job->filename = NULL;
  1375.     }
  1376.     if (job->username) {
  1377.     free((char*)job->username);
  1378.     job->username = NULL;
  1379.     }
  1380.     if (job->job_id) {
  1381.     free((char*)job->job_id);
  1382.     job->job_id = NULL;
  1383.     }
  1384. }
  1385.  
  1386.  
  1387. /**************************************************************************
  1388.  *
  1389.  * Function: submit_job
  1390.  *
  1391.  * Description: Submits a job for printing. A print job structure pointer
  1392.  *    is returned that can be used to subsequently cancel or track the
  1393.  *    status of the job. This pointer is reused by this function so users
  1394.  *    wishing to preserve the data in the structure should copy the
  1395.  *    structure.
  1396.  *
  1397.  * Parameters: 
  1398.  *    job_source (I) - the job to print. This is a pointer to the union of 
  1399.  *        structures indicating the job source. The first field
  1400.  *        describes the job type (eg. filename, fd, etc.).
  1401.  *    printer (I) - printer on which to print job. If NULL then default
  1402.  *              printer is used.
  1403.  *    num_copies (I) - number of copies
  1404.  *    copy (I) - Copy flag. If 1 then file is copied to spooling dir. If
  1405.  *        0 a link is created.
  1406.  *    mail (I) - Mail flag. If 1 then mail is sent on job print completion.
  1407.  *        If 0, no mail is sent.
  1408.  *    title (I) - title to appear on banner page.
  1409.  *    options (I) - string of spooling system/printer specific options.
  1410.  *        Set to NULL if none.
  1411.  *
  1412.  * Return: If no error, a pointer to a print job structure is returned. If
  1413.  *    the information in this structure is to be maintained and more jobs
  1414.  *    are to be submitted, this structure should be copied to a user buffer.
  1415.  *    NULL is returned and SLerrno is set if an error has occurred.
  1416.  *
  1417.  **************************************************************************/
  1418.  
  1419. static SLPrintJob* submit_job(SLJobSourceUnion *job_source,
  1420.             const char *printer, int num_copies, int copy,
  1421.             int mail, const char *title, const char *options)
  1422. {
  1423.     char *job_id;
  1424.     char *def_printer;
  1425.     time_t jtime;
  1426.     struct tm *jtm;
  1427.  
  1428.     /*
  1429.      * Make sure we have a valid spooler selected
  1430.      */
  1431.     CHECK_DEF_SPOOLER_PTR;
  1432.  
  1433.     /*
  1434.      * Perform basic sanity checks on the parameters
  1435.      */
  1436.     if (num_copies < 1)
  1437.     RETURN_ERROR_PTR(SL_ERR_NUM_COPIES);
  1438.     if (copy != 0 && copy != 1)
  1439.     RETURN_ERROR_PTR(SL_ERR_JOB_COPY);
  1440.     if (mail != 0 && mail != 1)
  1441.     RETURN_ERROR_PTR(SL_ERR_MAIL);
  1442.  
  1443.     /*
  1444.      * Initialize the job structure
  1445.      */
  1446.     init_job(&print_job);
  1447.  
  1448.     /*
  1449.      * Get the default printer name if no printer specified
  1450.      */
  1451.     if (!printer) {
  1452.     if (SLGetDefPrinterName(&def_printer) < 0)
  1453.         return NULL;
  1454.     printer = def_printer;
  1455.     } else if (_SLIsEmpty(printer))
  1456.     RETURN_ERROR_PTR(SL_ERR_BAD_PRINTER_NAME);
  1457.  
  1458.     /*
  1459.      * Call the appropriate function
  1460.      */
  1461.     if (def_sptr->submit_job_func(job_source, printer, num_copies,
  1462.                 copy, mail, title, options, &job_id) < 0)
  1463.     return NULL;
  1464.  
  1465.     /*
  1466.      * Fill out the info structure
  1467.      */
  1468.     print_job.spooler = def_spooler;
  1469.     print_job.printer = strdup(SL_CHAR_CAST(printer));
  1470.     if (job_source->type == SL_JOB_FILENAME)
  1471.         print_job.filename =
  1472.             strdup(SL_CHAR_CAST(job_source->filename_job.filename));
  1473.     else
  1474.         print_job.filename = strdup("Standard Input");
  1475.     print_job.username = strdup(def_sptr->find_username());
  1476.     print_job.job_id = (job_id) ? strdup(job_id): NULL;
  1477.  
  1478.     /*
  1479.      * Put in the time stamp. We zero out the seconds because lpstat
  1480.      * tends to report job queue time stamps only to the minute
  1481.      */
  1482.     jtime = time((time_t*)NULL);
  1483.     jtm = localtime(&jtime);
  1484.     jtm->tm_sec = 0;
  1485.     print_job.time_stamp = mktime(jtm);
  1486.     
  1487.     return &print_job;
  1488. }
  1489.  
  1490.  
  1491. /**************************************************************************
  1492.  *
  1493.  * Function: sort_plist
  1494.  *
  1495.  * Description: Performs a Shell sort on the printer list to sort the list
  1496.  *    case independently in alphabetical order by local name. The Shell
  1497.  *    sort is used because we will ussually be dealing with very few
  1498.  *    items in the list.
  1499.  *
  1500.  * Parameters: 
  1501.  *    plist (I,O) - printer list to be sorted
  1502.  *    num (I) - number of printers in the list
  1503.  *
  1504.  * Return: none
  1505.  *
  1506.  **************************************************************************/
  1507.  
  1508. static void sort_plist(SLPrinterStruct *plist, register int num)
  1509. {
  1510.     register int i, j, k, s, *ap;
  1511.     static int a[] = { 9, 5, 3, 2, 1, 0};
  1512.     SLPrinterStruct x;
  1513.  
  1514.     if (!plist || num < 2)
  1515.     return;
  1516.  
  1517.     for (ap = a; *ap; ap++) {
  1518.     k = *ap;
  1519.     s = -k;
  1520.     for (i = k; i < num; i++) {
  1521.         x = plist[i];
  1522.         j = i - k;
  1523.         if (!s) {
  1524.         s = -k;
  1525.         plist[++s] = x;
  1526.         }
  1527.         while (j >= 0 && j < num && 
  1528.             strcasecmp(x.local_name, plist[j].local_name) < 0) {
  1529.         plist[j + k] = plist[j];
  1530.         j -= k;
  1531.         }
  1532.         plist[j + k] = x;
  1533.     }
  1534.     }
  1535. }
  1536.